import java.util.LinkedList;
/*
 * Store.java
 * Version 0.1
 *
 */
import javax.swing.JOptionPane;

/**
 * This class contains all the initial units of each resource and allows players
 * to purchase them. The class is responsible for properly updating the players'
 * and the stores values upon purchases.
 * 
 * @author GT Five-O
 * @version v1.0b
 * 
 */
public class Store implements java.io.Serializable {

    private LinkedList<Food> food = new LinkedList<Food>();
    private LinkedList<Energy> energy = new LinkedList<Energy>();
    private LinkedList<Ore> ore = new LinkedList<Ore>();
    private LinkedList<Mule> mule = new LinkedList<Mule>();
    private GameScreen board;
    private static Mule soldMule;
    private static boolean muleSelection = false;
    private static boolean muleSold = false;

    /**
     * constructor for the store class.
     * 
     * @param board
     *            , that gets the state of the board when the game was closed.
     */
    public Store(GameScreen board) {
        this.board = board;
        loadStoreData();
    }

    /**
     * getter for the player's name
     * 
     * @return
     */
    public String getPlayerName() {
        return board.getCurrent().getPlayerName();
    }

    /**
     * getter for the amount of food available for sale
     * 
     * @return
     */
    public int getFood() {
        return food.size();
    }

    /**
     * getter for the amount of energy available for sale
     * 
     * @return
     */
    public int getEnergy() {
        return energy.size();
    }

    /**
     * getter for the amount of ore available for sale
     * 
     * @return
     */
    public int getOre() {
        return ore.size();
    }

    /**
     * getter for the amount of mules available for sale
     * 
     * @return
     */
    public int getMule() {
        return mule.size();
    }

    /**
     * creates a new Food unit
     */
    public void addFood() {
        food.add(new Food());
    }

    /**
     * creates a new Energy unit
     */
    public void addEnergy() {
        energy.add(new Energy());
    }

    /**
     * creates a new Ore unit
     */
    public void addOre() {
        ore.add(new Ore());
    }

    /**
     * creates a new Mule unit
     */
    public void addMule() {
        mule.add(new Mule());
    }

    /**
     * returns the boolean that checks if the mule has been sold to the player
     * 
     * @return
     */
    public boolean checkMuleSold() {
        return muleSold;
    }

    /**
     * setter for the boolean that checks if the mule has been sold
     * 
     * @param b
     *            true if the mule has been successfully sold
     */
    public void setMuleSold(boolean b) {
        muleSold = b;
    }

    /**
     * allows user to buy food (make sure that the player has enough money and
     * there is a food item available for sale
     * 
     * @return if user has enough money and there are enough foods available
     */
    public boolean[] sellFood() { // sells food to player
        boolean[] result = new boolean[2];
        if ((food.size() > 0) && checkPlayerMoney(GameConstants.FOOD_PRICE)) {
            result[0] = true;
            result[1] = true;
            transferFood();
            board.getCurrent().buying(GameConstants.FOOD_PRICE);
            return result;
        } else {
            result[0] = false;
            if (food.size() < 1) {
                result[1] = false;
            } else {
                result[1] = true;
            }
        }
        return result;
    }

    /**
     * Removes a Food unit from the player and adds one to the store
     */
    public void buyFood() {// buys food from player
        Food current = board.getCurrent().removeFood();
        if (current != null) {
            addFood();
            board.getCurrent().addMoney(GameConstants.FOOD_PRICE);
        } else {
            JOptionPane.showMessageDialog(board, "No Food Left to sell!");
        }
    }

    /**
     * method to transfer food from store to current player
     */
    public void transferFood() {
        Food current = food.removeLast();
        board.getCurrent().addFood(current);
    }

    /**
     * allows user to buy ore (make sure that the player has enough money and
     * there is a ore unit available for sale
     * 
     * @return if user has enough money and there are enough ore units available
     */
    public boolean[] sellOre() {
        boolean[] result = new boolean[2];
        if ((ore.size() > 0) && checkPlayerMoney(GameConstants.ORE_PRICE)) {
            result[0] = true;
            result[1] = true;
            transferOre();
            board.getCurrent().buying(GameConstants.ORE_PRICE);
            return result;
        } else {
            result[0] = false;
            if (ore.size() < 1) {
                result[1] = false;
            } else {
                result[1] = true;
            }
        }
        return result;
    }

    /**
     * Removes a Ore unit from the player and adds one to the store
     */
    public void buyOre() {// buys ore from player
        Ore current = board.getCurrent().removeOre();
        if (current != null) {
            addOre();
            board.getCurrent().addMoney(GameConstants.ORE_PRICE);
        } else {
            JOptionPane.showMessageDialog(board, "No Ores Left to sell!");
        }
    }

    /**
     * removes ore from the store and addes it to the current player's list
     */
    private void transferOre() {
        Ore current = ore.removeFirst();
        board.getCurrent().addOre(current);
    }

    /**
     * allows user to buy energy units (make sure that the player has enough
     * money and there is a energy unit available for sale
     * 
     * @return if user has enough money and there are enough energy units
     *         available
     */
    public boolean[] sellEnergy() {
        boolean[] result = new boolean[2];
        if ((energy.size() > 0) && checkPlayerMoney(GameConstants.ENERGY_PRICE)) {
            result[0] = true;
            result[1] = true;
            transferEnergy();
            board.getCurrent().buying(GameConstants.ENERGY_PRICE);
            return result;
        } else {
            result[0] = false;
            if (energy.size() < 1) {
                result[1] = false;
            } else {
                result[1] = true;
            }
        }
        return result;
    }

    /**
     * Removes a Energy unit from the player and adds one to the store
     */
    public void buyEnergy() {
        Energy current = board.getCurrent().removeEnergy();
        if (current != null) {
            addEnergy();
            board.getCurrent().addMoney(GameConstants.ENERGY_PRICE);
        } else {
            JOptionPane.showMessageDialog(board, "No Energy Left to sell!");
        }
    }

    /**
     * Transfers a Energy unit from the store to the current player
     */
    private void transferEnergy() {
        Energy current = energy.removeFirst();
        board.getCurrent().addEnergy(current);
    }

    /**
     * removes a mule unit from the store if available
     * 
     * @return if there are any mules in the store
     */
    public boolean[] sellMule(String muleType, Property property) {
        boolean[] result = new boolean[2];
        if ((mule.size() > 0) && checkPlayerMoney(mule.getFirst().getPrice())) {
            result[0] = true;
            result[1] = true;
            muleSold = true;
            soldMule = mule.removeLast();
            soldMule.setType(muleType);
            soldMule.setProperty(property);
            board.getCurrent().addMule(soldMule);
            return result;
        } else {
            result[0] = false;
            if (mule.size() < 1) {
                result[1] = false;
                muleSold = false;
            } else {
                result[1] = true;
                muleSold = false;
            }
        }
        return result;
    }

    /**
     * setter for boolean controlling when the mule is being selected
     * 
     * @param b
     */
    public void setMuleSelection(boolean b) {
        muleSelection = b;
    }

    /**
     * allows the user to select which property he/she wants to add the mule and
     * then places the mule
     */
    public void muleSelection() {
        JOptionPane.showMessageDialog(board,
                "Please select one of your properties to emplace the mule on.");
        muleSelection = true;
        board.focusPane();
        while (muleSelection) {
            board.setMulePhase(true);
            try {
                Thread.sleep(1000);
                if (board.mulePlaced() && board.validMulePlacement()) {
                    board.setMuleType(soldMule.getType());
                    muleSelection = false;
                    JOptionPane.showMessageDialog(board, "MulePlaced!");
                    board.nextCard();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        board.setVPlace(false);
    }

    /**
     * checks if a player can afford a price
     * 
     * @param n
     *            the price being compared to user's cash
     * @return if the player has enough money
     */
    private boolean checkPlayerMoney(int n) {
        return board.getCurrent().affordable(n);
    }

    /**
     * creates the initial items in the store. It adds food, energy and mules to
     * the store inventory.
     */
    public void loadStoreData() {

        for (int i = 0; i < 16; i++) {
            food.add(new Food());
            energy.add(new Energy());
        }

        for (int i = 0; i < 25; i++) {
            mule.add(new Mule());
        }

    }

}
